/************************************************************************
 * SMLib - State Model Library
 * Copyright (C) 2012-2013 Ali Khalili (khalili_DOT_ir_@SIGN_gmail_DOT_com)
 * **********************************************************************
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License (LGPL) published 
 * by the Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version. This program is distributed without any
 * warranty. See the GNU Lesser General Public License for more details. 
 * ***********************************************************************
 * File         :     
 * Description  :     
 * Change log   :     
 * To Do        :
 ************************************************************************/
using System;
using System.Collections.Generic;
using SMLib.Automata.Base;
using SMLib.Automata.MM;
using System.Text;

namespace SMLib.Automata.MM
{
	/// <summary>
	/// Random trace generator.
	/// </summary>
	public class MM_TraceGenerator
	{
		/// <summary>
		/// The average length of the traces
		/// </summary>
		public static int avLen = 20;

		/// <summary>
		/// The average difference
		/// </summary>
		public static int avDiff = 20;

		/// <summary>
		/// The number of traces
		/// </summary>
		public static int num = 2000;

		public static List<Sequence> Generate (IBlackBox_MM m)
		{
			List<Sequence> traces = new List<Sequence> ();
			Alphabet alph = m.InputAlphabet;
			Random rng = new Random ();
			for (int i=0; i<num; i++) {
				Sequence s = new Sequence ();
				traces.Add (s);
				m.Reset ();
				int len;

				//len = avLen + rng.Next ((int)(((double)avDiff)*avLen / 100));
				if(rng.Next(2)==0)
					len = avLen + rng.Next (avDiff);
				else
					len = avLen - rng.Next (avDiff);

				for (int j=0; j<len; j++) {
					ISymbol input = alph [rng.Next (alph.Size)];
					ISymbol output = m.Step (input);
					s.AddPair (input, output);
				}
			}
			return traces;
		}

		public static List<Sequence> Generate (MealyMachine m)
		{
			SMLib.Automata.MM.SUL_Emulator_MM emul = new SUL_Emulator_MM (m);
			return Generate (emul);
		}


		public static  void GenerateAndSave (IBlackBox_MM m, string path)
		{
			List<Sequence> seq = Generate (m);
			StringBuilder sb = new StringBuilder ();
			foreach (Sequence s in seq)
				sb.AppendLine (s.ToString ());
			System.IO.File.WriteAllText (path, sb.ToString ());
		}


		public static  void GenerateAndSave (MealyMachine m, string path)
		{
			SMLib.Automata.MM.SUL_Emulator_MM emul = new SUL_Emulator_MM (m);
			GenerateAndSave (emul, path);
		}
	}
}

